#ifndef _STRUCT_H_
#define _STRUCT_H_ 
#include <igraph/igraph.h>


/* FUNCTION ALIAS */
/* typedef int (init_func)(struct args_t *, void**); */
/* typedef int (load_file_func)(FILE *, igraph_vector_ptr_t*); */

/* typedef void (print_func)(FILE *, void*); */
/* typedef void (log_func)(void*); */
/* typedef void (free_func)(void**); */
/* FUNCTION ALIAS */

typedef  struct my_adjlist_t { int vn, en; igraph_vector_ptr_t *al; } my_adjlist_t;

struct msg_buf_t { igraph_vector_ptr_t *inmsg,*outmsg; int nfrag; /* log_func* log; print_func *print ; */ };

struct edge_t { int eid, src, dst, attr; } ;

struct vertex_t { int vid,ncon,vsize,*attr,locid,fid; igraph_vector_int_t *fids ; };

struct Fragment { int fid,innerv_it; igraph_vector_ptr_t *innerv; my_adjlist_t*local_adjlist, *global_adjlist; int innerv_size; };

struct pair_t { int vid, dist; };

struct arguments { char *load_strategy; int silent, parallel, verbose,ncon,nfrag,max_step; char *output_file,*rfile,*vfile,*efile,*query_file; }; 

#define ARGS_STRUCT_MEMBERS\
        struct msg_buf_t *messages;\
int nfrag;\
void*result;\
igraph_vector_ptr_t *vertices, *edges;\
struct Fragment *fragment;\
my_adjlist_t *global_adjlist;\
int vn,en;\
void *query;

struct args_t { ARGS_STRUCT_MEMBERS  };

struct step_timer_t { double evalt, synct; };

struct grape_plugin_t 
{

        int (*result_init_func)(struct args_t*, void **);
        void (*result_destroy_func)(void*);
        void (*msg_log_func)(void*);
        void (*msg_print_func)(FILE *, void *);
        void (*msg_destroy_func)(void*);
        int (*query_load_func)(FILE *, igraph_vector_ptr_t*);
        void (*query_destroy_func)(void*);
        void * (*query_copy_func)(void*);

        void* (*peval)(void*); 
        void* (*inceval)(void*);
        void* (*assemble)(struct args_t *,int);


};

struct grape_file_t
{
        FILE *vfile, *efile, *rfile;
        FILE *query_file,  *dat;
};

struct grape_data_t
{
        int vn,en,ncon,qn,max_step,nfrag;
        int load_strategy, nstep, parallel;
};

struct grape_app_t
{
        char *app_name, *doc, *arg_doc;
};

struct grape_var_t 
{

        pthread_t threads[N_FRAG];

        pthread_attr_t joinable_attr;

        struct args_t args[N_FRAG];

        /* the fragment array that representes the local graph */ 
        struct Fragment fragments[N_FRAG];

        /* two parts of the message buffer : IN and OUT */
        struct msg_buf_t  messages[N_FRAG];

        /* the partial result array that keep partial_result of each fragment during each step */
        void* results[N_FRAG];

        igraph_vector_ptr_t timer;

};

struct grape_graph_t
{
        my_adjlist_t global_adjlist;
        igraph_vector_int_t fragtable;
        igraph_vector_ptr_t vertices, edges, all_queries;
};

enum load_strategy_t { BOTH_IN_OUT=0, ONLY_IN=1, ONLY_OUT=2 };


enum timers_t {

        LOAD_TIMER=0,
        EVAL_TIMER=1,
        INCEVAL_TIMER=2,
        BCAST_TIMER=3,
        SYNC_TIMER=4,
        ASSEM_TIMER=5,

        ALL_LOAD_TIMER=6,
        ALL_EVAL_TIMER=7,
        EACH_Q_TIMER=8
};

#endif

